package org.zjt.agent.bytebuddy;

import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import java.lang.reflect.Method;

import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.function.BinaryOperator;
/**
 * {@link net.bytebuddy.implementation.Implementation}
 * @author juntao.zhang
 * @version V1.0
 * @Description: TODO
 * @Package org.zjt.agent.bytebuddy
 * @date 2017/12/3 13:20
 */
public class Interceptor {

    @RuntimeType
    public static Object intercept(@SuperCall Callable<?> call, @Origin Method method, @AllArguments Object[] arguments) {

        if (Objects.equals("IUserManagerService".toLowerCase(),String.valueOf(arguments[0]).toLowerCase())){
            System.err.println("-----------------");
        }

        System.out.printf("----------intercept-----arguments:%s------method:%s-----\n",
                Arrays.stream(arguments).map(String::valueOf).reduce((s, s2) -> s + String.format("%s,",s2)),method.getName());

        StackTraceElement[] stackElements = Thread.currentThread().getStackTrace();
        if (stackElements != null) {
            for (int i = 0; i < stackElements.length; i++) {
                System.out.println(String.format("%s:%s\t%s() ",
                        stackElements[i].getClassName(),
                        stackElements[i].getLineNumber(),
                        stackElements[i].getMethodName()));
            }
        }

        long startTim = System.currentTimeMillis();
        Object rtnObj = null;
        try {
            //方法拦截后,调用call方法,程序继续执行
            rtnObj = call.call();
            System.out.printf("返回的信息 rtnObj :%s",rtnObj);
        } catch (Throwable e) {
           e.printStackTrace();
        } finally {
            long endTime = System.currentTimeMillis();
            System.out.printf("time :%s",String.valueOf(((endTime - startTim) /1000)));
        }
        return rtnObj;
    }

}
